home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 301-325 / disk_319 / cnewssrc / cnews.src.lzh / input / bdecode.c next >
C/C++ Source or Header  |  1980-01-01  |  2KB  |  119 lines

  1. /*
  2.  * bdecode [file]
  3.  */
  4. #include <stdio.h>
  5. #include "coder.h"
  6. char *myname, *inputfile = "(stdin)";
  7.  
  8. main(argc, argv) 
  9.     char **argv;
  10. {
  11.     register long word;
  12.     register int c, bcount;
  13.     register FILE *fin = stdin, *fout = stdout;    /* in regs for speed */
  14.     register char *map, *p;
  15.     register long nbytes;
  16.     register int crc;
  17.     long nbytes2;
  18.     int w, crc2;
  19.     char buf[512];
  20.     extern char *index();
  21.  
  22.     myname = argv[0];
  23.     if (sizeof(word) < 4)
  24.         fprintf(stderr, "%s: word size too small\n", myname), exit(1);
  25.     if (argc > 2)
  26.         fprintf(stderr, "Usage: %s [file]\n", myname), exit(1);
  27.     if (argc == 2) {
  28.         if ((fin = fopen(argv[1], "r")) == NULL) {
  29.             fprintf(stderr, "%s: ", myname);
  30.             perror(argv[1]);
  31.             exit(1);
  32.         }
  33.         inputfile = argv[1];
  34.     }
  35.     /* skip to beginning of encoded data */
  36.     do {
  37.         if (fgets(buf, sizeof buf, fin) == NULL)
  38.             fatal("Missing header");
  39.         /* trim trailing blanks (sigh) */
  40.         p = index(buf, '\n');
  41.         if (p == 0)
  42.             continue;
  43.         while (*--p == ' ')
  44.             ;
  45.         p[1] = '\n';
  46.         p[2] = '\0';
  47.     } while (strcmp(buf, header) != 0);
  48.     
  49.     /* define input mapping table */
  50.     map = buf+1;
  51.     for (c = 0; c < 256; c++)
  52.         map[c] = 64;        /* illegal */
  53.     for (c = 0; c < 64; c++)
  54.         map[ENCODE(c)] = c;
  55.     map[EOF] = 65;        /* special cases */
  56.     map['/'] = 66;
  57.  
  58.     word = 0;
  59.     bcount = 4;
  60.     nbytes = 0;
  61.     crc = 0;
  62. #define PUTC(x)  { c = (x) & 0xff; CRC(crc, c); putc(c, fout); nbytes++; }
  63.     for (;;) {
  64.         c = map[getc(fin)];
  65.         if ((unsigned)c < 64) {
  66.             word <<= 6;
  67.             word |= c;
  68.             if (--bcount == 0) {
  69.                 PUTC(word >> 16);
  70.                 PUTC(word >>  8);
  71.                 PUTC(word);
  72.                 word = 0;
  73.                 bcount = 4;
  74.             }
  75.             continue;
  76.         }
  77.         switch (c) {
  78.  
  79.         default:
  80.             /*
  81.              * Ignore stuff not in the code set.
  82.              */
  83.             continue;
  84.  
  85.         case 65:    /* EOF */
  86.             fatal("Unexpected EOF");
  87.  
  88.         case 66:    /* '/' */
  89.             /* trailer follows: %d%x */
  90.             c = getc(fin);
  91.             if (fscanf(fin, "%x", &w) != 1)
  92.                 fatal("Corrupted input (trailer)");
  93.             switch (c) {
  94.             case '2': PUTC(w >> 8);
  95.             case '1': PUTC(w);
  96.             case '0': break;
  97.             default: fatal("Corrupted input (trailer)");
  98.             }
  99.             /*
  100.              * Byte count and CRC follow.
  101.              */
  102.             if (fscanf(fin, "%ld%x", &nbytes2, &crc2) != 2)
  103.                 fatal("Corrupted input (missing byte count/CRC)");
  104.             if (nbytes2 != nbytes)
  105.                 fatal("Corrupted input (byte count is wrong)");
  106.             if (crc2 != (crc & 0xffff))
  107.                 fatal("Corrupted input (CRC mismatch)");
  108.             exit(0);
  109.         }
  110.     }
  111. }
  112.  
  113. fatal(s)
  114.     char *s;
  115. {
  116.     fprintf(stderr, "%s: %s: %s\n", myname, inputfile, s);
  117.     exit(2);
  118. }
  119.